`timescale 1ns/1ps
`include "define.sv"

module fifo_to_array_tb;

    reg clk;
    reg reset;
    reg [1:0] matrix_type;
    reg [31:0] data_in_a, data_in_b;
    reg data_valid_in_a, data_valid_in_b;
    reg array_ready;
    wire [31:0] data_out_a [0:31];
    wire [31:0] data_out_b [0:31];
    wire wr_en_a [0:31];
    wire wr_en_b [0:31];
    wire done;

    // 实例化待测模块
    fifo_to_array dut (
        .clk(clk),
        .reset(reset),
        .matrix_type(matrix_type),
        .data_in_a(data_in_a),
        .data_valid_in_a(data_valid_in_a),
        .data_in_b(data_in_b),
        .data_valid_in_b(data_valid_in_b),
        .data_out_a(data_out_a),
        .wr_en_a(wr_en_a),
        .data_out_b(data_out_b),
        .wr_en_b(wr_en_b),
        .array_ready(array_ready),
        .done(done)
    );

    // 时钟生成
    initial clk = 0;
    always #5 clk = ~clk;

    // 测试流程
    initial begin
        integer i;
        // 初始化
        reset = 1;
        array_ready = 0;
        matrix_type = `m16n16k16; // 先用16x16
        data_in_a = 0;
        data_in_b = 0;
        data_valid_in_a = 0;
        data_valid_in_b = 0;
        #20;
        reset = 0;
        array_ready = 1;
        #10;

        // 通道A/B输入数据
        for (i = 0; i < 16*16; i = i + 1) begin
            data_in_a = i;
            data_in_b = 1000 + i;
            data_valid_in_a = 1;
            data_valid_in_b = 1;
            #10;
        end
        data_valid_in_a = 0;
        data_valid_in_b = 0;

        // 等待done信号
        wait(done == 1);
        $display("Test for m16n16k16 done!");

        // 切换matrix_type，测试8x32
        reset = 1; #20; reset = 0;
        matrix_type = `m8n32k16;
        #10;
        for (i = 0; i < 8*16; i = i + 1) begin
            data_in_a = i;
            data_valid_in_a = 1;
            #10;
        end
        data_valid_in_a = 0;
        for (i = 0; i < 32*16; i = i + 1) begin
            data_in_b = 2000 + i;
            data_valid_in_b = 1;
            #10;
        end
        data_valid_in_b = 0;
        wait(done == 1);
        $display("Test for m8n32k16 done!");

        // 结束仿真
        #50;
        $finish;
    end

    // 可选：监控信号
    initial begin
        $monitor("T=%0t, done=%b, data_valid_in_a=%b, data_valid_in_b=%b, wr_en_a[0]=%b, wr_en_b[0]=%b", $time, done, data_valid_in_a, data_valid_in_b, wr_en_a[0], wr_en_b[0]);
    end

endmodule